import json
from typing import List

import requests
from sqlalchemy.orm import Session

from server.app.cloud_ide.model import IdeImage, IdeRegistry
from server.app.cloud_ide.schema.ide_image.request.ide_image_create_request import IdeImageCreateRequest
from server.app.cloud_ide.schema.ide_image.request.ide_image_update_request import IdeImageUpdateRequest
from server.framework.core.logger import logger
from server.framework.core.settings import settings
from server.framework.utils.kubernetes.kubernetes_client import KubernetesClient


class IdeImageService:
    def get_ide_images_by_registry_id(self, db: Session, registry_id: str) -> List[IdeImage]:
        results = db.query(IdeImage).filter(IdeImage.ide_registry_id == registry_id).all()
        return results

    def get_ide_image_by_id(self, db: Session, image_id: str) -> IdeImage:
        entity = db.query(IdeImage).filter(image_id == IdeImage.id).one()
        return entity

    def find_ide_image_by_name(self, db: Session, registry_id: str, name: str) -> IdeImage:
        entity = db.query(IdeImage).filter(registry_id == IdeImage.ide_registry_id and IdeImage.name == name).first()
        return entity

    def delete_ide_image(self, db: Session, ids: list):
        try:
            db.query(IdeImage).filter(IdeImage.id.in_(ids)).delete(synchronize_session=False)
            db.commit()
            return True
        except Exception as e:
            logger.error(e)
            return False

    def create_ide_image(self, db: Session, data: IdeImageCreateRequest) -> bool:
        try:
            entity = IdeImage(**data.dict())
            db.add(entity)
            db.commit()
            return True
        except Exception as e:
            logger.error(e)
            return False

    def get_ide_image_list(self, db: Session, ide_registry_id: str, name: str,
                           page_size: int, current_page: int):
        query = db.query(IdeImage.id,
                         IdeImage.name,
                         IdeImage.note,
                         IdeImage.git_url,
                         IdeImage.status,
                         IdeImage.created,
                         IdeImage.version,
                         IdeRegistry.name.label('ide_registry'),
                         IdeRegistry.id.label('ide_registry_id'))
        query = query.join(IdeImage, IdeRegistry.id == IdeImage.ide_registry_id)
        if ide_registry_id is not None:
            query = query.filter(IdeRegistry.id == ide_registry_id)
        if name is not None:
            query = query.filter(IdeImage.name.like("%" + name + "%"))

        total = query.count()
        items = query.limit(page_size).offset((current_page - 1) * page_size).all()
        return items, total

    def update_ide_image(self, db: Session, data: IdeImageUpdateRequest) -> bool:
        try:
            db.query(IdeImage).filter(IdeImage.id == data.id).update(data.dict())
            db.commit()
            return True
        except Exception as e:
            logger.error(e)
            return False

    def get_ide_build_log(self, db: Session, id: str) -> str:
        entity: IdeImage = db.query(IdeImage).filter(IdeImage.id == id).one()

        argo_content = requests.get(
            f'{settings.argo_url}/api/v1/workflows/{settings.kubernetes_namespace}/{entity.job_id}/log?logOptions.container=main&podName={entity.job_id}').text
        result = ''
        for i in argo_content.split('\n'):
            try:
                line_entity = json.loads(i)
                result += line_entity['result']['content'] + '\n'
            except:
                pass
        return result

    def build_ide_image(self, db: Session, id: str) -> bool:
        try:
            entity: IdeImage = db.query(IdeImage).filter(IdeImage.id == id).one()
            registry: IdeRegistry = db.query(IdeRegistry).filter(IdeRegistry.id == entity.ide_registry_id).one()

            dynamic_args = {
                'gitlab_url': entity.git_url,
                'image_name': f'{registry.registry}/{entity.name}:{entity.version}'
            }

            kubernetes_manager = KubernetesClient()
            workflow_id = kubernetes_manager.run_build_image_workflow(dynamic_args)

            entity.job_id = workflow_id
            entity.status = 1
            db.commit()
            return True
        except Exception as e:
            logger.error(e)
            return False
